import re,requests
from threading import Thread

import openpyxl
import pandas as pd
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
import xlrd
import matplotlib.pyplot as plt

# 需求：抓取详细地址，详情链接，房型，户型，面积，出售价格，登记时间，对数据进行图表分析，并以excel形式添加到本地


url = "https://www.lgfdcw.com/cs/"

# 写一个fake_header假装是浏览器访问,避免有些网站不给爬
fake_header = {
"User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
    " Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.41"
}


# 获取源代码
def get_content(url,headers):
    try:

        # 获取源代码
        resp = requests.get(url,headers = headers)
        # 解码成gbk要不然会乱码
        content = resp.content.decode('gbk')

    # 异常处理
    except Exception as e:
        print(e)

    finally:
        # 记得要关闭爬虫，以免访问次数过多有些网站不给访问
        resp.close()

        return content


# 利用正则表达式抓取想要的内容，格式化输出
def content_format():
    try:
        r = re.compile(r'<td align="left">.*?"(?P<href>.*?)".*?<strong>(?P<address>.*?)</strong>.*?<a href=\?fwtype=0>'
                       r'(?P<house_type>.*?)</a>.*?<a href=.*?>(?P<house_type2>.*?)</a>.*?<td>(?P<area>.*?)</td>.*?'
                       r'<font color="#FF0000">(?P<money>.*?)</font>.*?<td>\[(?P<date>.*?)]'
                       r'</td>',re.S)
        result = r.findall(get_content(url,fake_header))
    # 异常处理
    except Exception as e:
        print(e)

    finally:
        # 遍历结果，格式化输出
        for item in result:
            print('  ')
            print("详情链接：https://www.lgfdcw.com/cs/%-25s 地址：%-23s 房型：%-9s 户型：%-15s 面积：%-10s 登记时间：%-8s" %
                  (item[0],item[1],item[2],item[3],item[4],item[6]))

            print("出售价格：%s " % (item[5]))
            print('  ')


# 生成dataframe,因为有很多地方需要用到dataframe，所以干脆写一个生成dataframe的函数
def create_dataframe():
    # 显示所有列
    pd.set_option('display.max_columns', None)
    # 处理数据
    r = re.compile(r'<td align="left">.*?"(?P<href>.*?)".*?<strong>(?P<address>.*?)</strong>.*?<a href=\?fwtype=0>'
                   r'(?P<house_type>.*?)</a>.*?<a href=.*?>(?P<house_type2>.*?)</a>.*?<td>(?P<area>.*?)</td>.*?'
                   r'<font color="#FF0000">(?P<money>.*?)</font>.*?<td>\[(?P<date>.*?)]'
                   r'</td>', re.S)
    result = r.findall(get_content(url, fake_header))
    # 详情链接列表
    href = []
    # 地址列表
    address = []
    # 房型列表
    house_type = []
    # 户型列表
    house_type2 = []
    # 面积列表
    area = []
    # 价格列表
    money = []
    # 日期列表
    date = []
    # 遍历数据，存入相应列表
    for item in result:
        href.append('https://www.lgfdcw.com/cs/' + item[0])
        address.append(item[1])
        house_type.append(item[2])
        house_type2.append(item[3])
        area.append(item[4])
        # 用正则表达式处理价格数据，因为有很多空白符和换行符，和不知道什么字符导致提取到的价格很多空白
        money.append(re.findall(r'\d+\.?\d?万元/?套?', item[5]))
        date.append(item[6])
    # 将价格列表的子列表的需要的数据提取出来，存到新列表里，方便dataframe转成excel时价格数据是str类型的
    money_change_single_list = []
    # 创建空列表，防止价格为空的情况
    empty_list = []
    for i in range(0, len(money)):
        if money[i] != empty_list:
            money_change_single_list.append(money[i][0])
        else:
            money_change_single_list.append('无标价')
    # 生成dataframe
    data = {
        '地址': address,
        '房型': house_type,
        '户型': house_type2,
        '面积': area,
        '登记时间': date,
        '出售价格': money_change_single_list,
        '详情链接': href
    }
    dataframe = pd.DataFrame(data, columns=['地址', '房型', '户型', '面积', '登记时间', '出售价格', '详情链接'])
    return dataframe


def save_as_excel():

    dataframe = create_dataframe()
    # print(dataframe)

    # 创建工作簿，写入，并保存
    wb = Workbook()
    ws = wb.active
    # 工作表名字
    ws.title = '龙港房地产爬虫项目'
    for x in dataframe_to_rows(dataframe):
        ws.append(x)

    # 保存成excel文件，注意如果已经运行成功过一次，再运行第二次时需要更改文件名，不然可能因为文件已存在而报异常
    wb.save('龙港房地产爬虫项目.xlsx')
    print('保存成功！')


# 画饼状图
def draw_pie():
    # 解决中文乱码
    plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']
    '''
        因为xlrd2.0.1不支持xlsx格式，所以要降低版本,在pycharm的terminal（命令行）输入以下命令
        pip uninstall xlrd
        pip install xlrd==1.2.0
        
    '''

    work_book = xlrd.open_workbook('龙港房地产爬虫项目.xlsx')
    sheet1_name = work_book.sheet_names()[0]
    sheet1_content = work_book.sheet_by_name(sheet1_name)
    # print(sheet1_content)
    cols_value = sheet1_content.col_values(3)
    # 三室二厅二卫一阳台
    type1 = 0
    # 一室一厅一卫一阳台
    type2 = 0
    # 四室二卫二厅一阳台
    type3 = 0
    # 五室二厅二卫二阳台
    type4 = 0
    for data in cols_value:
        if data == '三室二厅二卫一阳台':
            type1 = type1 + 1
        if data == '一室一厅一卫一阳台':
            type2 = type2 + 1
        if data == '四室二卫二厅一阳台':
            type3 = type3 + 1
        if data == '五室二厅二卫二阳台':
            type4 = type4 + 1
    data2 = [type1,type2,type3,type4]
    labels = ['三室二厅二卫一阳台', '一室一厅一卫一阳台', '四室二卫二厅一阳台', '五室二厅二卫二阳台']
    colors = ['blue', 'orange', 'green', 'red']
    explode = [0,0,0,0]

    plt.xlim(0, 12)
    plt.ylim(0, 12)
    plt.title('户型')
    # 设置x，y轴刻度一致，这样饼图才能是圆的
    plt.axis('equal')

    # 参数设置
    plt.pie(
        x=data2,
        explode=explode,
        labels=labels,
        colors=colors,
        autopct='%.2f%%',
        startangle=300,
        labeldistance=1.1,
        pctdistance = 0.6,
        center=(6, 6),
        radius=1,
        counterclock=False,
        wedgeprops={'linewidth': 0.1, 'edgecolor': 'green'},
        textprops={'fontsize': 8, 'color': 'black'}
    )
    plt.legend(labels, loc='upper right')
    plt.xticks(())  # 不显示坐标
    plt.yticks(())  # 不显示坐标
    plt.show()


if __name__ == '__main__':
    # 多线程，虽然爬取一页用多线程没什么意义，但是爬很多页的时候效率很高
    # thread = Thread(target=get_content,args=(url,fake_header,))
    # thread.start()
    # thread.join()
    draw_pie()





